/*
 * $Id: AOItem.java 27 2013-05-20 13:31:39Z antonyhands@gmail.com $
 */
package ru.olympus.antonyhands.ao.data.entities;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import ru.olympus.antonyhands.ao.data.AOData;
import ru.olympus.antonyhands.ao.util.LongUtilities;
import ru.olympus.antonyhands.ao.util.StringPair;
import ru.olympus.antonyhands.ao.util.StringUtilities;

/**
 * @author AntonyHands
 * @since 14.02.2012
 */
public class AOItem extends AOItemBase
{

    public static final String TAG_NAME = "item";

    private static final String ATTRIBUTE_CATEGORY = "category";
    private static final String ATTRIBUTE_FIXED_PRICE = "fixed-price";
    private static final String ATTRIBUTE_MARKET_PRICE = "market-price";

    /**
     * Категория товара
     */
    private ItemCategory category;

    /**
     * Фиксированная цена (если есть)
     */
    private Long fixedPrice;

    /**
     * Рыночная цена
     */
    private Long marketPrice;

    /**
     * Крафтовый скилл, позволяющий делать данный предмет (если можно)
     */
    private CraftInfo craftInfo;

    /**
     * Предметы, которые можно скрафтить из данного
     */
    private List<CraftInfo> craftableItems = new ArrayList<CraftInfo>();

    /**
     * Варианты обмена, в которых можно получить данный предмет
     */
    private List<ItemExchange> exchangeFrom = new ArrayList<ItemExchange>();

    /**
     * Варианты обмена, в которых можно потратить этот предмет
     */
    private List<ItemExchange> exchangeTo = new ArrayList<ItemExchange>();

    // ==========================================================

    public AOItem()
    {
        // for the sake of persistence
    }

    public AOItem(String code, String title, ItemCategory category)
    {
        super(code, title);
        this.category = category;
    }

    @Override
    public String getTagName()
    {
        return TAG_NAME;
    }

    public Long getFixedPrice()
    {
        return fixedPrice;
    }

    public void setFixedPrice(Long fixedPrice)
    {
        this.fixedPrice = fixedPrice;
    }

    @Override
    public List<StringPair> getAttributes()
    {
        List<StringPair> attributes = super.getAttributes();
        attributes.add(new StringPair(ATTRIBUTE_CATEGORY, category.getCode()));
        attributes.add(new StringPair(ATTRIBUTE_FIXED_PRICE, StringUtilities.longToString(fixedPrice)));
        attributes.add(new StringPair(ATTRIBUTE_MARKET_PRICE, StringUtilities.longToString(marketPrice)));
        return attributes;
    }

    @Override
    public void setAttributes(List<StringPair> attributes)
    {
        super.setAttributes(attributes);
        for (StringPair pair : attributes)
        {
            if (ATTRIBUTE_CATEGORY.equals(pair.getKey()))
                category = AOData.getInstance().getItemCategoryByCode(pair.getValue());
            else if (ATTRIBUTE_FIXED_PRICE.equals(pair.getKey()))
                fixedPrice = StringUtilities.stringToLong(pair.getValue());
            else if (ATTRIBUTE_MARKET_PRICE.equals(pair.getKey()))
                marketPrice = StringUtilities.stringToLong(pair.getValue());
        }
    }

    public ItemCategory getItemCategory()
    {
        return category;
    }

    public void setCraftInfo(CraftInfo craftInfo)
    {
        this.craftInfo = craftInfo;
    }

    public CraftInfo getCraftInfo()
    {
        return craftInfo;
    }

    public void setMarketPrice(Long marketPrice)
    {
        this.marketPrice = marketPrice;
    }

    public Long getMarketPrice()
    {
        return marketPrice;
    }

    public void addCraftableItem(CraftInfo craftableItemInfo)
    {
        craftableItems.add(craftableItemInfo);
    }

    public void removeCraftableItem(CraftInfo craftableItemInfo)
    {
        craftableItems.remove(craftableItemInfo);
    }

    public List<CraftInfo> listCraftableItems()
    {
        return craftableItems;
    }

    public Long getBestPrice()
    {
        return LongUtilities.getMin(fixedPrice, marketPrice, getCraftPrice());
    }

    public Long getCraftPrice()
    {
        if (craftInfo == null)
            return null;
        Long res = new Long(0);
        for (ItemQuantityPair iq : craftInfo.listInputItemsData())
            res += iq.getValue() * iq.getKey().getBestPrice();
        return res / craftInfo.getResultItemData().getValue();
    }

    public List<AOItem> listItemsInCraftHierarchy()
    {
        HashSet<AOItem> res = new HashSet<AOItem>();
        res.add(this);
        if (getCraftInfo() != null)
            for (AOItem i : craftInfo.listSourceItems())
                res.addAll(i.listItemsInCraftHierarchy());
        return new ArrayList<AOItem>(res);
    }
}
